﻿using DevExpress.Xpf.Bars.Native;
using FastMember;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Data;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using TeBigCommonUI.Common;

namespace TeBigCommonUI.Items
{
    public class SimpleGridControl : BaseItemControl
    {

        public Thickness RowMargin
        {
            get { return (Thickness)GetValue(RowMarginProperty); }
            set { SetValue(RowMarginProperty, value); }
        }

        // Using a DependencyProperty as the backing store for RowMargin.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RowMarginProperty =
            DependencyProperty.Register("RowMargin", typeof(Thickness), typeof(GridControl),
                new PropertyMetadata(new Thickness(0)));



        public double RowHeight
        {
            get { return (double)GetValue(RowHeightProperty); }
            set { SetValue(RowHeightProperty, value); }
        }

        // Using a DependencyProperty as the backing store for RowHeight.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RowHeightProperty =
            DependencyProperty.Register("RowHeight", typeof(double), typeof(GridControl),
                new PropertyMetadata(36d));



        public Brush GridBrush
        {
            get { return (Brush)GetValue(GridBrushProperty); }
            set { SetValue(GridBrushProperty, value); }
        }

        // Using a DependencyProperty as the backing store for GridBrush.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty GridBrushProperty =
            DependencyProperty.Register("GridBrush", typeof(Brush), typeof(GridControl),
                new PropertyMetadata(new SolidColorBrush(Color.FromArgb(0x32, 0x80, 0x80, 0x80))));



        public Brush CellBackground
        {
            get { return (Brush)GetValue(CellBackgroundProperty); }
            set { SetValue(CellBackgroundProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CellBackground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CellBackgroundProperty =
            DependencyProperty.Register("CellBackground", typeof(Brush), typeof(GridControl),
                new PropertyMetadata(null));



        public Brush HeaderBackground
        {
            get { return (Brush)GetValue(HeaderBackgroundProperty); }
            set { SetValue(HeaderBackgroundProperty, value); }
        }

        // Using a DependencyProperty as the backing store for HeaderBackground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty HeaderBackgroundProperty =
            DependencyProperty.Register("HeaderBackground", typeof(Brush), typeof(GridControl),
                new PropertyMetadata(null));



        public Brush RowBackground
        {
            get { return (Brush)GetValue(RowBackgroundProperty); }
            set { SetValue(RowBackgroundProperty, value); }
        }

        // Using a DependencyProperty as the backing store for RowBackground.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RowBackgroundProperty =
            DependencyProperty.Register("RowBackground", typeof(Brush), typeof(GridControl),
                new PropertyMetadata(null));




        public int ColumnCount
        {
            get { return (int)GetValue(ColumnCountProperty); }
            set { SetValue(ColumnCountProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SeriesCount.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ColumnCountProperty =
            DependencyProperty.Register("ColumnCount", typeof(int), typeof(SimpleGridControl), new PropertyMetadata(1));

        public ObservableCollection<GridColumn> GridColumns
        {
            get { return (ObservableCollection<GridColumn>)GetValue(GridColumnsProperty); }
        }

        // Using a DependencyProperty as the backing store for SeriesDataSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty GridColumnsProperty =
            DependencyProperty.Register("GridColumns", typeof(ObservableCollection<GridColumn>), typeof(SimpleGridControl),
                new PropertyMetadata(new ObservableCollection<GridColumn>()));

        public SimpleGridControl()
        {
            SetValue(GridColumnsProperty, new ObservableCollection<GridColumn>());
        }


        public IEnumerable DataSource
        {
            get { return (IEnumerable)GetValue(DataSourceProperty); }
            set { SetValue(DataSourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DataSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DataSourceProperty =
            DependencyProperty.Register("DataSource", typeof(IEnumerable), typeof(SimpleGridControl),
                new PropertyMetadata(OnDataSourceChanged));

        private static void OnDataSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is GridControl grid)
            {
                if (e.OldValue is INotifyCollectionChanged old_value)
                {
                    old_value.CollectionChanged -= grid.OnDataSourceCollectionChanged;
                }

                if (e.NewValue is INotifyCollectionChanged new_value)
                {
                    new_value.CollectionChanged += grid.OnDataSourceCollectionChanged;
                }
            }
        }
    }


    /// <summary>
    /// Interaction logic for GridControl.xaml
    /// </summary>
    public partial class GridControl : SimpleGridControl
    {



        public GridControl()
        {
            this.Foreground = BrushHelper.CreateLinearGradientBrush(Color.FromArgb(0xff, 255, 204, 0), 0.5, 0, 90);
            this.FontSize = 20;
            this.FontWeight = FontWeights.Regular;

            InitializeComponent();

            this.Loaded += GridControl_Loaded;
        }

        private void GridControl_Loaded(object sender, RoutedEventArgs e)
        {
            
        }

        private void ScrollViewer_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
        {
            var items = TreeHelper.GetChildren<ScrollViewer>(grid_main);

            foreach (var item in items)
            {
                item.ScrollToVerticalOffset(item.VerticalOffset - e.Delta);
            }

            e.Handled = true;
        }

        internal void OnDataSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            items_control.UpdateTarget();
        }
    }

    public class GridValueConverter : IMultiValueConverter
    {
        // Token: 0x06002AC3 RID: 10947 RVA: 0x0007BAA4 File Offset: 0x00079CA4
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (values.Length == 2)
            {
                if (values[0] != null && this.IsValidValue(values[0]) && values[1] is GridColumn col)
                {
                    var key = col.ValueDataMember;

                    object v;

                    switch (values[0])
                    {
                        case DataRowView row_view:
                            v = row_view[key];
                            break;
                        case DataRow row:
                            v = row[key];
                            break;
                        default:
                            v = values[0].FastGetProperty(key);
                            break;
                    }

                    var s = string.Format(col.FormatString, v);

                    if (col.NegativeBrush != null)
                    {
                        if (double.TryParse(v.ToString(), out var dValue))
                            return s + (dValue < 0 ? "↓" : "↑");
                    }

                    return s;
                }
            }

            return null; //$"Value{MyRandom.NextInt(0, 100)}";
        }

        // Token: 0x06002AC4 RID: 10948 RVA: 0x0007BB28 File Offset: 0x00079D28
        public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class GridColorConverter : IMultiValueConverter
    {
        // Token: 0x06002AC3 RID: 10947 RVA: 0x0007BAA4 File Offset: 0x00079CA4
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if (values.Length == 3)
            {
                if (values[0] != null && this.IsValidValue(values[0]) && values[1] is GridColumn col && values[2] is GridControl gc)
                {
                    var key = col.ValueDataMember;

                    object v;

                    switch (values[0])
                    {
                        case DataRowView row_view:
                            v = row_view[key];
                            break;
                        case DataRow row:
                            v = row[key];
                            break;
                        default:
                            v = values[0].FastGetProperty(key);
                            break;
                    }

                    if (col.TopN > 0 && col.TopNBrush != null && gc.DataSource is IEnumerable<object> ie)
                    {


                        var list = ie.Select(r => r.FastGetProperty(col.ValueDataMember)).OrderByDescending(r => r).ToList();

                        if (list.IndexOf(v) >= 0 && list.IndexOf(v) < col.TopN)
                        {
                            if (!(int.TryParse(v.ToString(), out int k) && k == 0))
                                return col.TopNBrush;
                        }
                    }


                    if (col.NegativeBrush != null)
                    {
                        if (double.TryParse(v.ToString(), out var dValue) && dValue < 0)
                            return col.NegativeBrush;
                    }


                    if (col.Foreground != null)
                        return col.Foreground;


                }

                if (values[2] is GridControl gc2)
                {
                    return gc2.Foreground;
                }
            }

            return null; //$"Value{MyRandom.NextInt(0, 100)}";
        }

        // Token: 0x06002AC4 RID: 10948 RVA: 0x0007BB28 File Offset: 0x00079D28
        public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class GridAlignmentConverter : IMultiValueConverter
    {
        // Token: 0x06002AC3 RID: 10947 RVA: 0x0007BAA4 File Offset: 0x00079CA4
        public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
        {

            if (value[0] is GridColumn col)
            {
                if (targetType == typeof(HorizontalAlignment))
                {
                    return col.HorizontalAlignment;
                }

                if (targetType == typeof(VerticalAlignment))
                {
                    return col.VerticalAlignment;
                }

                if (targetType == typeof(Thickness))
                {
                    return col.CellPadding;
                }
            }

            return null; 
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

    public class GridColumnWidthConverter : IMultiValueConverter
    {
        public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value.Length == 2)
            {
                if (value[0] is GridColumn col && value[1] is GridControl gc)
                {
                    if (col.WidthPercent != null)
                    {
                        return col.WidthPercent.Value;
                    }
                    else
                    {
                        return 100.0 / gc.GridColumns.Count;
                    }
                }

            }

            return null; 
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}